#include "at24cxx.h"
#include "softI2c.h"
#include "delay.h"

// 初始化IIC接口
void AT24CXX_Init(void) {
    i2cInit();
}

// 在AT24CXX指定地址读出一个数据
// ReadAddr:开始读数的地址
// 返回值:读到的数据
uint8_t AT24CXX_ReadOneByte(uint16_t ReadAddr) { // AT24C02:0x00~0xFF
    uint8_t temp=0;
    i2cStart();
    if(EE_TYPE > AT24C16) {
        i2cSendByte(0XA0);	   // 发送写命令
        i2cWaitAck();
        i2cSendByte(ReadAddr>>8); // 发送高地址
    } else
        i2cSendByte(0XA0+((ReadAddr/256)<<1)); // 发送器件地址0XA0,写数据
    i2cWaitAck();
    i2cSendByte(ReadAddr%256); // 发送低地址
    i2cWaitAck();
    i2cStart();
    i2cSendByte(0XA1); // 进入接收模式
    i2cWaitAck();
    temp=i2cReadByte(0);
    i2cStop(); // 产生一个停止条件
    return temp;
}

// 在AT24CXX指定地址写入一个数据
// WriteAddr  :写入数据的目的地址
// DataToWrite:要写入的数据
void AT24CXX_WriteOneByte(uint16_t WriteAddr,uint8_t DataToWrite) {
    i2cStart();
    if(EE_TYPE>AT24C16) {
        i2cSendByte(0XA0); // 发送写命令
        i2cWaitAck();
        i2cSendByte(WriteAddr>>8); // 发送高地址
    } else 
        i2cSendByte(0XA0+((WriteAddr/256)<<1)); // 发送器件地址0XA0,写数据
    i2cWaitAck();
    i2cSendByte(WriteAddr%256); // 发送低地址
    i2cWaitAck();
    i2cSendByte(DataToWrite); // 发送字节
    i2cWaitAck();
    i2cStop(); // 产生一个停止条件
    delay_ms(10); // EEPROM的写入速度比较慢，加入延迟
}

// 检查AT24CXX是否正常
// 这里用了24XX的最后一个地址(255)来存储标志字.
// 如果用其他24C系列,这个地址要修改
// 返回1:检测失败
// 返回0:检测成功
uint8_t AT24CXX_Check(void) {
    uint8_t temp;
    temp=AT24CXX_ReadOneByte(255);//避免每次开机都写AT24CXX
    if(temp==0X55)
        return 0;
    else { //排除第一次初始化的情况
        AT24CXX_WriteOneByte(255,0X55);
        temp=AT24CXX_ReadOneByte(255);
        if(temp==0X55)
            return 0;
    }
    return 1;
}

// 在AT24CXX里面的指定地址开始读出指定个数的数据
// ReadAddr :开始读出的地址 对24c02为0~255
// pBuffer  :数据数组首地址
// NumToRead:要读出数据的个数
void AT24CXX_Read(uint16_t ReadAddr,uint8_t *pBuffer,uint16_t NumToRead) {
    while(NumToRead) {
        *pBuffer++=AT24CXX_ReadOneByte(ReadAddr++);
        NumToRead--;
    }
}

// 在AT24CXX里面的指定地址开始写入指定个数的数据
// WriteAddr :开始写入的地址 对24c02为0~255
// pBuffer   :数据数组首地址
// NumToWrite:要写入数据的个数
void AT24CXX_Write(uint16_t WriteAddr,uint8_t *pBuffer,uint16_t NumToWrite) {
    while(NumToWrite--) {
        AT24CXX_WriteOneByte(WriteAddr,*pBuffer);
        WriteAddr++;
        pBuffer++;
    }
}
